import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support.select import Select
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys
from selenium.common.exceptions import TimeoutException, NoSuchElementException
from datetime import time,datetime
png_dir = "D:\\gao1\\UIweb\\Png"


class Base():
    # 初始化驱动
    def __init__(self, driver=None):
        """初始化驱动，若未传入则默认创建Chrome驱动"""
        if driver is None:
            self.driver = webdriver.Chrome()
            self.driver.maximize_window()  # 默认最大化窗口
        else:
            self.driver = driver
            self.driver.implicitly_wait(10)  # 全局隐式等待，降低元素定位失败概率


    # #调用 driver.get(url) 访问 URL。
    # 用 try-except 捕获异常（如 URL 无效、网络错误），打印日志方便调试。
    def open_url(self, url):
        """打开指定URL"""
        try:
            self.driver.get(url)
            print(f"成功打开URL: {url}")
        except Exception as e:
            print(f"打开URL失败: {e}")
            # 2. 生成带时间戳的截图文件名（避免重名）
            timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
            screenshot_path = f"{png_dir}/open_url_failed_{timestamp}.png"

            # 3. 截取当前页面并保存
            if self.driver.save_screenshot(screenshot_path):
                print(f"截图已保存至: {screenshot_path}")
            else:
                print("截图保存失败")

    def quit(self):
        """关闭浏览器并退出驱动"""
        self.driver.quit()
        print("浏览器已关闭")

    # 封装定位方法
    def find_element(self, loc):
        """
        基础元素定位（显式等待+异常处理）
        :param loc: 定位器，格式为(By.XX, "表达式")
        :return: 找到的WebElement对象，未找到则返回None
        """
        try:
            # 显式等待元素可见（最长20秒，每0.5秒检查一次）
            WebDriverWait(self.driver, 20, 0.5).until(
                lambda driver: driver.find_element(*loc).is_displayed()
            )
            return self.driver.find_element(*loc)
        # 异常处理：捕获 TimeoutException
        # （超时未找到）和 NoSuchElementException（元素不存在），打印错误日志并返回 None，避免程序直接崩溃。
        except Exception as e:
            print(f"元素定位失败: {loc}，错误信息: {e}")


            timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
            screenshot_path = f"{png_dir}/open_url_failed_{timestamp}.png"

            # 3. 截取当前页面并保存
            if self.driver.save_screenshot(screenshot_path):
                print(f"截图已保存至: {screenshot_path}")
            else:
                print("截图保存失败")

    # 点击事件
    def click(self, loc):
        self.find_element(loc).click()

    # 输入框输入事件
    def send_keys(self, loc, text):
        self.find_element(loc).send_keys(text)

    # 封装text()文本断言
    def text(self, loc):
        return self.find_element(loc).text

    # 封装clear操作
    def clear(self, loc):
        self.find_element(loc).clear()

    # 滚动任意像素分装
    def scrollTo_x(self, x):
        self.driver.execute_script(f'window.scrollTo(0,{x})')

    # 滚动到底部
    def scrollTo_H(self):
        self.driver.execute_script('window.scrollTo(0,document.body.scrollHeight)')

    # 切换窗口
    def window(self):
        self.driver.switch_to.window(self.driver.window_handles[-1])

    # 封装alert
    def alert_accept(self):
        alert = self.driver.switch_to.alert
        alert.accept()

    def confirm_dismiss(self):
        confirm = self.driver.switch_to.alert
        confirm.dismiss()

    def prompt_accept(self):
        prompt = self.driver.switch_to.alert
        prompt.send_keys("这是一prompt弹窗")
        prompt.accept()

    def prompt_dismiss(self):
        prompt = self.driver.switch_to.alert
        prompt.send_keys('这是一个prompt弹窗')
        prompt.dismiss()

    # 获取时间戳
    def get_time(self):
        return time.strftime("%Y%m%d%H%M%S", time.localtime())

    def screenshot(self):
        self.driver.save_screenshot(self.get_time() + '.png')

    # 封装frame框架
    def go_frame(self, loc):
        self.driver.switch_to.frame(self.find_element(loc))

    # 封装退出frame框架
    def frame_connect(self):
        self.driver.switch_to.default_content()

    # 封装select - lindex
    def select_index(self, loc, x):
        index = Select(self.find_element(loc))
        index.select_by_index(x)

    # 封装select - value
    def select_value(self, loc, x):
        value = Select(self.find_element(loc))
        value.select_by_value(x)

    # 封装select - visible_text
    def select_text(self, loc, info):
        text = Select(self.find_element(loc))
        text.select_by_visible_text(info)

    # 封装鼠标双击
    def double(self, loc):
        ActionChains(self.driver).double_click(self.find_element(loc)).perform()

    # 封装鼠标三击
    def three_click(self, loc):
        ActionChains(self.driver).double_click(self.find_element(loc)).click(self.find_element(loc)).perform()

    # 封装鼠标右击
    def context_click(self, loc):
        ActionChains(self.driver).context_click(self.find_element(loc)).perform()

    # 封装鼠标悬停
    def move_to_elment(self, loc):
        ActionChains(self.driver).move_to_element(self.find_element(loc)).perform()

    # 封装鼠标拖拽
    def drag_and_drop(self, loc, x, y):
        ActionChains(self.driver).drag_and_drop_by_offset(self.find_element(loc), x, y).perform()

    # 封装鼠标按住不放
    def click_and_hold(self, loc):
        ActionChains(self.driver).click_and_hold(self.find_element(loc)).perform()

    # 封装鼠标单击
    def sbclick(self, loc):
        ActionChains(self.driver).click(self.find_element(loc)).perform()

    # 键盘封装(回车)
    def keys_enter(self, loc):
        self.send_keys(loc, Keys.ENTER)

    def key_tab(self, loc):
        self.send_keys(loc, Keys.TAB)
        self.send_keys(loc, Keys.LEFT)
        self.send_keys(loc, Keys.ADD)
        self.send_keys(loc, Keys.DOWN)
        self.send_keys(loc, Keys.META)
        self.send_keys(loc, Keys.ARROW_UP)
        self.send_keys(loc, Keys.ARROW_DOWN)
        self.send_keys(loc, Keys.ARROW_LEFT)
        self.send_keys(loc, Keys.ARROW_RIGHT)
        self.send_keys(loc, Keys.DELETE)
        self.send_keys(loc, Keys.COMMAND)

    # 截图与时间
    def get_timestamp(self):
        """获取当前时间戳（格式：年月日时分秒）"""
        return time.strftime("%Y%m%d%H%M%S", time.localtime())

    def jtbc(self, name=None):
        """截图保存（默认用时间戳命名）"""
        if name:
            filename = f"{name}.png"
        else:
            filename = f"{self.get_timestamp()}.png"
        self.driver.save_screenshot(filename)
        print(f"截图已保存: {filename}")